<script setup>
import { ref, reactive, toRefs, getCurrentInstance, computed, onMounted, onUnmounted, nextTick, watch } from "vue";
import * as echarts from "echarts";
import { getEnergyLineLossDirectrix } from "@/api/energy/consumeMeasure";
import { getConsumeCostOverViewByclass } from "@/api/energy/consumeCost";
import modelTitle from "@/views/common/components/modelTitle/index.vue";
import btnImageAndData from "@/views/common/energy/components/btnImageAndData/index.vue";

const { proxy } = getCurrentInstance();
const props = defineProps({
  queryParams: {
    type: Object,
    default: () => {}
  },
  currentNode: {
    type: String,
    default: ""
  },
  currentSystem: {
    type: String,
    default: ""
  },
  activeName: {
    type: String,
    default: "all"
  }
});

const state = reactive({
  loading: false,
  tableData: [],
  resData: {
    costRatio: [],
    costSummaryTable: [],
    costTrend: {
      axisMeasureDetailDTOS: []
    }
  },
  energyTypeList: [], // 耗能趋势多选
  tableHeader: [
    {
      label: "序号",
      type: "index",
      prop: "index"
    },
    {
      label: "耗能单元",
      prop: "system",
      align: "left"
    },
    {
      label: "总费用(万元)",
      prop: "summaryCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["summaryCost"],
      width: "124"
    },
    {
      label: "电(万元)",
      prop: "electricityCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["electricityCost"],
      width: "100"
    },
    {
      label: "水(万元)",
      prop: "waterCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["waterCost"],
      width: "100"
    },
    {
      label: "再生水(万元)",
      prop: "reclaimCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["reclaimCost"],
      width: "100"
    },
    {
      label: "天然气(万元)",
      prop: "ngCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["ngCost"],
      width: "124"
    },
    {
      label: "蒸汽/热水(万元)",
      prop: "hotSteamCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["hotSteamCost"],
      width: "110"
    },
    {
      label: "大宗气(万元)",
      prop: "gasCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["gasCost"],
      width: "124"
    },
    {
      label: "热量(万元)",
      prop: "heatCost",
      align: "left",
      sortable: true,
      sortOrders: ["ascending", "descending", null],
      sortBy: ["heatCost"],
      width: "124"
    }
  ],
  lineLoss: {
    lineName: [],
    xaxis: [],
    yaxis: []
  }
});
const { loading, tableHeader, tableData, resData, energyTypeList } = toRefs(state);

const queryParams = computed(() => props.queryParams);
const currentNode = computed(() => props.currentNode);
const activeName = computed(() => props.activeName);

const ratioChartRef = ref(null);
const trendChartRef = ref(null);
const ratioOptions = ref(null);
const trendOptions = ref(null);
const echartsKey = ref(Math.random().toString(36).slice(2, 10));
const switchType = ref("bar");
const switchText = ref("切换折线图");

let chartObj = {};

// 耗能列表的合计，正常是后端返回，后端不好整，由前端继续计算
let totalObj = {
  electricityCost: 0,
  gasCost: 0,
  hotCost: 0,
  ngCost: 0,
  steamCost: 0,
  summaryCost: 0,
  system: "合计",
  waterCost: 0
};
// 饼图
const labelLayoutFn = data => {
  const options = {
    // toolbox: {
    //   show: true,
    //   feature: {
    //     saveAsImage: {
    //       title: "点击保存为图片"
    //     }
    //   }
    // },
    color: ["#5B8FF9", "#5AD8A6 ", "#FFB910"],
    tooltip: {
      trigger: "item",
      formatter: `{a} <br/>{b}: {c} ({d}%)`
    },
    grid: {
      left: "0px",
      top: "40px",
      right: "10px",
      bottom: "10px",
      containLabel: true
    },
    legend: {
      orient: "horizontal", // 垂直排列
      type: "scroll", // 使用滚动的图例
      data: (data && data.map(el => el.name)) || []
    },
    series: [
      {
        name: "耗能占比",
        type: "pie",
        labelLine: {
          length: 10
        },
        label: {
          formatter: `{c|{c}}(万元) \n{d|{d}%}`,
          rich: {
            c: {
              fontSize: 16
            },
            d: {
              fontSize: 16,
              fontWeight: "bold"
            }
          }
        },
        radius: "50%",
        data: data || [],
        top: "10%",
        height: "90%"
      }
    ]
  };
  let myChart = echarts.init(ratioChartRef.value);
  chartObj.ratioChartRef = myChart;
  if (data?.length > 0) {
    myChart.clear();
    myChart.setOption(options);
    ratioOptions.value = options;
  } else {
    myChart.clear();
    ratioOptions.value = null;
  }
};
// 折线图
const labelLayoutFnTrend = (xData, serisData, yAxis, legend) => {
  let serisAry = serisData;
  // 当选中，总能耗折标煤时，才出现基准线
  if (activeName.value === "all") {
    // 绩效基准组成的数组
    let lineLossAry = [];
    state.lineLoss?.yaxis?.forEach(item => {
      let obj = {
        emphasis: { focus: "series" },
        type: "line",
        name: item.facName + "绩效基准",
        data: item?.value || []
      };
      legend.push(item.facName + "绩效基准");
      lineLossAry.push(obj);
    });
    serisAry = serisData.concat(lineLossAry);
  }

  const options = {
    // toolbox: {
    //   show: true,
    //   feature: {
    //     saveAsImage: {
    //       title: "点击保存为图片"
    //     }
    //   }
    // },
    tooltip: {
      trigger: "axis",
      confine: true, // 确保 tooltip 显示在容器内
      formatter: function (params) {
        let total = 0;
        // 蒸汽/热水块，只需要合计GJ类型的数据
        let paramsGj = params.filter(item => item.seriesName.includes("GJ"));
        if (paramsGj.length) {
          total = paramsGj.reduce((sum, item) => {
            item.value = item.value ? item.value : 0;
            return sum + Number(item.value);
          }, 0);
        } else {
          total = params.reduce((sum, item) => {
            item.value = item.value ? item.value : 0;
            return sum + Number(item.value);
          }, 0);
        }
        total = total.toFixed(2);
        // 生成内容
        let html = `<div>${params[0].name}</div>`;
        params.forEach(item => {
          html += `<div style="display: flex;align-items: center"><div style="width: 10px;height: 10px;background-color: ${item.color};border-radius: 50%"></div>&nbsp;<div style="flex: 1">${item.seriesName}</div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div style="font-weight: bold;">${item.value ? item.value : "-"}</div></div>`;
        });
        html += `<div style="display: flex"><span style="flex-grow: 1; margin-left: 14px">合计</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;float: right">${total}</span></d>`;
        return html;
      }
    },
    legend: {
      type: "scroll", // 设置图例分页类型为滚动
      icon: "rect",
      orient: "horizontal", // 水平排列
      right: "center", // 水平居中
      itemWidth: 37, // 图例标记的图形宽度
      itemHeight: 13, // 图例标记的图形高度
      selected: {},
      data: legend || []
    },
    grid: {
      left: "10px",
      right: "10px",
      bottom: "3%",
      containLabel: true
    },
    xAxis: {
      type: "category",
      data: xData || []
    },
    yAxis: yAxis,
    series: serisAry || []
  };
  return options;
};

const getParams = () => {
  let dimensionObj = {
    Hourly: "H",
    Daily: "D",
    Monthly: "M",
    Yearly: "Y"
  };
  let dimension = dimensionObj[queryParams.value.queryTimeGranularity];
  let startDate = queryParams.value.startTime;
  let endDate = queryParams.value.endTime;
  let sysId = currentNode.value || "";
  return {
    dimension,
    startDate,
    endDate,
    sysId
  };
};
// const
/** 导出按钮操作 */
const handlerExport = (val1, val2, val3) => {
  let name = props.currentSystem || "";
  const { dimension, startDate, endDate } = getParams();
  if (val1 === "data") {
    const params = {
      dimension,
      startDate,
      endDate,
      type: val2,
      costSummaryTable: state.resData.costSummaryTable,
      costTrend: state.resData.costTrend,
      label: activeName.value || ""
    };
    proxy.download("post", "/energy/energyCost/exportMeasurement", params, `消耗成本-${name}费用排行.xlsx`);
  } else {
    let myChart = chartObj[val3];
    if (!myChart) return;
    // 获取Base64图片数据
    const imgUrl = myChart.getDataURL({
      type: "png",
      pixelRatio: 2,
      backgroundColor: "#fff"
    });
    // 创建并触发下载链接
    const link = document.createElement("a");
    link.href = imgUrl;
    link.download = "chart.png";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
};
const dataSourse = ref([]);
const sortTable = (v, data) => {
  if (!data || data.length <= 0) {
    tableData.value = [];
    return;
  }
  // 神拷贝
  const deepAry = JSON.parse(JSON.stringify(data));
  switch (v) {
    case "all":
      tableData.value = deepAry.sort((a, b) => {
        return b.summaryCost - a.summaryCost;
      });
      break;
    case "electricity":
      tableData.value = deepAry.sort((a, b) => {
        return b.electricityCost - a.electricityCost;
      });
      break;
    case "running":
      tableData.value = deepAry.sort((a, b) => {
        return b.waterCost - a.waterCost;
      });
      break;
    case "reclaim":
      tableData.value = deepAry.sort((a, b) => {
        return b.reclaimCost - a.reclaimCost;
      });
      break;
    case "ng":
      tableData.value = deepAry.sort((a, b) => {
        return b.ngCost - a.ngCost;
      });
      break;
    case "hotSteam":
      tableData.value = deepAry.sort((a, b) => {
        return b.hotSteamCost - a.hotSteamCost;
      });
      break;
    case "gas":
      tableData.value = deepAry.sort((a, b) => {
        return b.gasCost - a.gasCost;
      });
      break;
    default:
      tableData.value = deepAry.sort((a, b) => {
        return b.summaryCost - a.summaryCost;
      });
      break;
  }
  // 合计保留两位小数
  Object.keys(totalObj).forEach(i => {
    if (i !== "system") {
      totalObj[i] = Number(totalObj[i]?.toFixed(2));
    }
  });
  // 把最后的合计加上
  tableData.value.push(totalObj);
  dataSourse.value = JSON.parse(JSON.stringify(tableData.value));
};

// 获取单位
const getUnit = () => {
  let danwei = "";
  if (activeName.value == "all") {
    danwei = "总费用（万元）";
  }
  if (activeName.value == "electricity") {
    danwei = "电（万元）";
  }
  if (activeName.value == "running") {
    danwei = "水（万元）";
  }
  if (activeName.value == "reclaim") {
    danwei = "再生水（万元）";
  }
  if (activeName.value == "ng") {
    danwei = "天然气（万元）";
  }
  if (activeName.value == "hotSteam") {
    danwei = "蒸汽/热水（万元）";
  }
  if (activeName.value == "gas") {
    danwei = "大宗气（万元）";
  }
  return danwei;
};

// 耗能趋势
const handleChangeTypeFn = v => {
  const data = resData.value;
  let seriesArr = [];
  let yaxisArr = {};
  let legend = [];
  let xData = [];
  let danwei = getUnit();
  yaxisArr = {
    type: "value",
    position: "left",
    name: danwei,
    alignTicks: true,
    offset: 0,
    nameTextStyle: {
      align: "left"
    },
    axisLine: {
      lineStyle: {
        width: 2
      }
    },
    axisLabel: {
      formatter: function (value) {
        if (value >= 1e12) {
          return (value / 1e12).toFixed(1) + "T"; // 万亿
        } else if (value >= 1e9) {
          return (value / 1e9).toFixed(1) + "B"; // 十亿
        } else if (value >= 1e6) {
          return (value / 1e6).toFixed(1) + "M"; // 百万
        } else if (value >= 1e3) {
          return (value / 1e3).toFixed(1) + "K"; // 千
        }
        return value;
      }
    }
  };
  // 处理数据
  if (data.costTrend.axisMeasureDetailDTOS && data.costTrend.axisMeasureDetailDTOS.length > 0) {
    xData = data.costTrend.axisMeasureDetailDTOS[0].xaxis;
    data.costTrend.axisMeasureDetailDTOS.forEach((item, index) => {
      if (energyTypeList.value.includes(item.sysId)) {
        legend.push(item.sysName || item.sysId);
        let eObj = item.yaxis.find(v => v.name === activeName.value);
        seriesArr.push({
          name: item.sysName || item.sysId,
          type: switchType.value,
          stack: "Total",
          data: eObj
            ? eObj.value.map(e => {
                if (e == null) {
                  return e;
                } else {
                  return Number(Number(e).toFixed(2));
                }
              })
            : [],
          emphasis: {
            focus: "series"
          }
        });
      }
    });
  }
  trendOptions.value = labelLayoutFnTrend(xData, seriesArr, yaxisArr, legend);
  let myChart = echarts.init(trendChartRef.value);
  chartObj.trendChartRef = myChart;
  myChart.clear();
  myChart.setOption(trendOptions.value);
};

watch(
  () => props.activeName,
  val => {
    nextTick(() => {
      tabSelectHandler(val);
    });
  }
);

const tabSelectHandler = v => {
  // 处理排序，饼图重绘
  sortTable(v, resData.value?.costSummaryTable);
  let data = [];
  if (v !== "all") {
    const findObj = resData.value?.costRatio && resData.value?.costRatio.find(el => el.kind === v);
    data =
      (findObj &&
        findObj.ratio &&
        findObj.ratio.map(item => {
          return {
            name: item.name,
            value: item.value ? Number(item.value).toFixed(2) : 0
          };
        })) ||
      [];
    labelLayoutFn(data);
  } else {
    data = resData.value?.costSummaryTable.map(el => {
      return {
        name: el.system,
        value: el.summaryCost ? Number(el.summaryCost).toFixed(2) : 0
      };
    });
    labelLayoutFn(data);
  }
  // 耗能趋势
  if (resData.value?.costTrend && resData.value?.costTrend?.axisMeasureDetailDTOS) {
    handleChangeTypeFn(energyTypeList.value);
  }
};

const getAll = async () => {
  try {
    state.loading = true;
    const { dimension, startDate, endDate, sysId } = getParams();
    let params = {
      dimension,
      startDate,
      endDate,
      factory: "",
      sysId
    };
    if (queryParams.value.startTime && queryParams.value.endTime) {
      const res = await getConsumeCostOverViewByclass(params);
      res.costSummaryTable = res?.costSummaryTable?.filter(item => item.system !== null);
      res?.costSummaryTable.forEach(item => {
        totalObj.electricityCost += item.electricityCost;
        totalObj.gasCost += item.gasCost;
        totalObj.hotCost += item.hotCost;
        totalObj.ngCost += item.ngCost;
        totalObj.steamCost += item.steamCost;
        totalObj.summaryCost += item.summaryCost;
        totalObj.waterCost += item.waterCost;
      });
      resData.value = res || {};
      // 趋势默认全选
      if (res?.costTrend && res?.costTrend?.axisMeasureDetailDTOS) {
        energyTypeList.value = res?.costTrend?.axisMeasureDetailDTOS.map(v => v.sysId);
      }
      nextTick(() => {
        tabSelectHandler("all");
      });
    }
  } catch (error) {
  } finally {
    state.loading = false;
  }
};

// 能源基准线-消耗计量
const getEnergyLineLossDirectrixData = async () => {
  try {
    const { dimension, startDate, endDate, sysId } = getParams();
    let params = {
      dimension,
      startDate,
      endDate,
      factory: "",
      sysId
    };
    if (queryParams.value.startTime && queryParams.value.endTime) {
      const res = await getEnergyLineLossDirectrix(params);
      if (res) {
        state.lineLoss = res;
      }
    }
  } catch (error) {}
};

// 点击左边的树的不同级，处理不同的情况
const handleSpecial = () => {
  // 月度、总能耗折标煤、厂务系统，才有能效基准线
  if (queryParams.value.queryTimeGranularity === "Monthly" && props.currentSystem === "厂务系统" && activeName.value === "all") {
    // getEnergyLineLossDirectrixData();
  } else {
    // 把值进行置空
    state.lineLoss = {
      lineName: [],
      xaxis: [],
      yaxis: []
    };
  }
};
let timerId = null;
onMounted(() => {
  handleSpecial();
  timerId = setTimeout(() => {
    getAll();
  }, 0);
});

onUnmounted(() => {
  clearTimeout(timerId);
});
const handleSwitch = () => {
  if (switchType.value === "bar") {
    switchType.value = "line";
    switchText.value = "切换堆积图";
  } else {
    switchType.value = "bar";
    switchText.value = "切换折线图";
  }
  // 耗能趋势
  if (resData.value?.costTrend && resData.value?.costTrend?.axisMeasureDetailDTOS) {
    handleChangeTypeFn(energyTypeList.value);
  }
};
const sortMethod = ({ order, prop }) => {
  if (tableData.value?.length) {
    const endInd = tableData.value?.length - 1;
    const endRow = tableData.value[endInd];
    const sordData = tableData.value.slice(0, endInd);
    if (!order) {
      // 无手动排序，按默认排序
      sortTable(props.activeName, resData.value?.costSummaryTable);
    } else {
      const newData = sordData.sort((a, b) => {
        if (order === "descending") {
          return b[prop] - a[prop];
        }
        return a[prop] - b[prop];
      });
      tableData.value = JSON.parse(JSON.stringify([...newData, endRow]));
    }
  }
};
</script>

<template>
  <div v-loading="loading" class="switchTableTabs">
    <div class="content-wrap">
      <px-row :gutter="16">
        <px-col :span="15">
          <div class="black">
            <modelTitle :title="'耗能费用趋势'" />
            <btnImageAndData
              v-has="'ALL_ENERGY_COST_CONSUMPTION_DOWNLOAD'"
              class="download"
              @exportChange="val => handlerExport(val, 'line', 'trendChartRef')"
            />
            <!-- <px-button v-has="'ALL_ENERGY_COST_CONSUMPTION_DOWNLOAD'" class="download" @click="handlerExport('line')">导出</px-button> -->
            <div v-if="resData?.costTrend?.axisMeasureDetailDTOS?.length" ref="trendChartRef" class="chart-wrap" />
            <px-empty v-else :image-size="50" />
            <div v-show="resData?.costTrend?.axisMeasureDetailDTOS?.length" class="switch-wrap" @click="handleSwitch">
              <px-icon><Switch size="small" /></px-icon><span class="text">{{ switchText }}</span>
            </div>
          </div>
        </px-col>
        <px-col :span="9">
          <div class="black">
            <modelTitle :title="'耗能占比'" />
            <btnImageAndData
              v-has="'ALL_ENERGY_COST_CONSUMPTION_DOWNLOAD'"
              class="download"
              :exportData="Boolean(false)"
              @exportChange="val => handlerExport(val, '', 'ratioChartRef')"
            />
            <div class="black-btm">
              <div v-if="resData?.costRatio?.length" :key="echartsKey" ref="ratioChartRef" class="chart-wrap" />
              <px-empty v-else :image-size="50" />
            </div>
          </div>
        </px-col>
      </px-row>
      <px-row :gutter="16" class="mg-top-16">
        <px-col :span="24">
          <div class="black">
            <modelTitle :title="'耗能费用排行'" />
            <btnImageAndData
              v-has="'ALL_ENERGY_COST_CONSUMPTION_DOWNLOAD'"
              class="download"
              :exportImage="Boolean(false)"
              @exportChange="val => handlerExport(val, 'table', '')"
            />
            <!-- <px-button v-has="'ALL_ENERGY_COST_CONSUMPTION_DOWNLOAD'" class="download" @click="handlerExport('table')">导出</px-button> -->
            <px-table
              v-if="tableData?.length"
              @sort-change="sortMethod"
              class="table-wrap"
              height="249px"
              :data="tableData"
              size="small"
              border
              stripe
              show-overflow-tooltip
            >
              <template v-for="item in tableHeader" :key="item.prop">
                <px-table-column v-if="item.type == 'index'" type="index" label="序号" width="60" align="center" />
                <px-table-column
                  v-else
                  :prop="item.prop"
                  :sortable="item.prop !== 'system' ? 'custom' : false"
                  :label="item.label"
                  :min-width="item.minwidth"
                />
              </template>
            </px-table>
            <px-empty v-else :image-size="50" />
          </div>
        </px-col>
      </px-row>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.switchTableTabs {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.content-wrap {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.px-row {
  flex: 1;
}

.mg-top-16 {
  margin-top: 16px;
}

.black {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 16px 24px;
  background-color: #fff;
  border-radius: 4px;

  .black-btm {
    display: flex;
    flex: 1;
    flex-direction: column;
  }

  .switch-wrap {
    position: absolute;
    top: 68px;
    right: 70px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;

    .text {
      font-size: 12px;
    }
  }
}

.table-wrap {
  flex: 1;
  margin-top: 16px;
}

.chart-wrap {
  flex: 1;
  margin-top: 16px;
}

.download {
  position: absolute;
  top: 16px;
  right: 24px;
}
</style>
